using System;
using System.Collections;
using System.Html;
using System.Runtime.CompilerServices;
using Awaiter;
using Nsb;
using Nsb.Classes;
using ThemeChain;
using WhirliGig.Classes;
using Yoshi.Classes;
using Yoshi.Fb;
using YoshiBase.Classes;
using jQueryApi;

namespace PlayNexus.Classes
{
    //
    // Page hiarchy: body > #PageMaster > #PageCenter > #PageContent||.<PageClassName>||Element > .PageCluster
    //

    [IgnoreNamespace]
    public abstract class BasicPage : ProfileTruple, IPage
    {
        public static readonly FbDataStore FbData = new FbDataStore();
        private static GigShow _gigShow;
        protected jQueryObject PageFooter;
        protected jQueryObject PageMaster;
        //protected jQueryObject PageCluster;
        private jQueryObject _focusElement;

        protected BasicPage()
        {
            Title = "Yoshi Page";
            PageMaster = jQuery.Select("#" + Master.PageMasterId);
            Inform.Log("Creating page instance FullClass={0}, PageName={1}", GetType().FullName, ThemeYoshi.CurrentPageName);

            if (Await.Files["Pages"] == null)
                new Await()
                    .LoadJson("Pages", Uri.App(Uri.Join(ThemeYoshi.PagesPartition, ThemeYoshi.PagesRowKey + ".txt")))
                    .HandleDl(Exceptions.BlobLoadError, Await.IgnoreAw)
                    .AddDx(delegate { ThemeYoshi.Pages = (PagesD) Await.Files["Pages"]; })
                    .Commit();
        }

        #region IPage Members

        public static string Title
        {
            get { return Document.Title; }
            set { Document.Title = value; }
        }

        public virtual void UpdatePage(PageUpdate pu)
        {
        }

        public void FocusEvent(jQueryEvent e)
        {
            _focusElement = Script.IsValue(e) ? jQuery.FromElement(e.Target) : null;
        }

        public bool IsFocused(jQueryObject el)
        {
            return _focusElement != null && el[0] == _focusElement[0];
        }

        public virtual void Destroy()
        {
        }

        #endregion

        protected void BasicBuildAw(Await awp)
        {
            new Await()
                .AddDl(
                    delegate(Await aw)
                    {
                        try
                        {
                            // Verify the page exists in the page table otherwise go to home page
                            bool tst = ThemeYoshi.Pages.pages[ThemeYoshi.CurrentPageName].Name.Length > 0;
                            aw.Done();
                        }
                        catch
                        {
                            Master.Log(String.Format("Failed to load page \"{0}\"", ThemeYoshi.CurrentPageName), Window.Location.Href, 0);
                            Window.SetTimeout(
                                delegate
                                {
                                    Storage.SetSession(ThemeYoshi.PageAttrKey, ThemeYoshi.DefaultPageClass);
                                    Storage.SetSession(ThemeYoshi.PageNameKey, ThemeYoshi.DefaultPageName);
                                    if (ThemeYoshi.CurrentPageName != ThemeYoshi.DefaultPageName)
                                        ThemeYoshi.ReloadPage();
                                }, 1);
                            aw.Abort();
                        }
                    })
                .AddDx(
                    delegate
                    {
                        //Inform.Debug("BasicBuildAw");
                        jQueryObject centerBox = jQuery.FromHtml("<div id='PageCenter'/>")
                            .AppendTo(PageMaster)
                            ;

                        Element = jQuery.FromHtml("<div id='PageContent'/>")
                            .AppendTo(centerBox)
                            .AddClass(GetType().Name)
                            ;

                    })
                .AddFn(BasicCluster)
                //.AddFn(BasicFooter)
                .AddAw(RefreshAw)
                .AddAw(PageAw)
                .AddDx(delegate { FileBlobBase.SvCnt--; })
                .Commit(awp);
        }

        public virtual void RefreshAw(Await awp)
        {
            awp.Done();
        }

        protected void PageAw(Await awp)
        {
            jQueryObject curateEl = jQuery.Select("#CurateElement");
            if (curateEl.Length == 0)
            {
                curateEl = jQuery.FromHtml("<div id='CurateElement'/>")
                    .AppendTo(Document.Body)
                    ;
            }

            CurateAw(awp, curateEl);
        }

        protected void BasicCluster()
        {
            jQuery.FromHtml("<div id='PageGigs' class='FrontContent'/>")
                .AppendTo(Element)
                ;
            //PageCluster = jQuery.FromHtml("<div class='PageCluster'/>")
            //    .AppendTo(Element)
            //    ;
        }

        //protected void BasicFooter()
        //{
        //    PageFooter = jQuery.FromHtml("<div class='PageFooter'/>")
        //        .AppendTo(Element)
        //        .Html("")
        //        ;
        //}

        public void ShowTopUser()
        {
            //if (TopBar != null)
            //    TopBar.ShowUser();
        }

        public void LoadPageCssAw(Await awp)
        {
            new Await()
                .LoadCss(Uri.Scripts("Css/" + GetType().Name + ".css"))
                .Commit(awp);
        }

        public void LoadNamespaceCssAw(Await awp)
        {
            new Await()
                .LoadCss(Uri.Scripts("Css/" + GetType().FullName.Split(".")[0] + ".css"))
                .Commit(awp);
        }

        public static void Retitle()
        {
            Title = ThemeYoshi.CurrentPage.Title ?? ThemeYoshi.CurrentPage.Face ?? ThemeYoshi.CurrentPage.Name;
        }

        public static void CurateAw(Await awp, jQueryObject curateElement)
        {
            bool curating = (bool) Storage.GetLocal(ThemeYoshi.CuratingKey);
            curateElement.Empty();
            jQueryObject slideControls = jQuery.FromHtml("<div class='SlideControls'/>").AppendTo(curateElement);

            string gigLib = Uri.Scripts("Scripts/WhirliGig.js");
            string gigLibEd = Uri.Scripts("Scripts/WhirliGigEdit.js");

            Await awx = new Await()
                //.WaitDx(delegate { return Master.Profile.MyId != null; })
                .LoadText("ColorPickerTable", Uri.Scripts("Data/GigColorPicker.html"))
            ;
            if (curating)
                awx
                    .LoadScript(gigLib)
                    .LoadScript(gigLibEd,
                                delegate(Await aw)
                                {
                                    if (_gigShow != null)
                                        _gigShow.Destroy();
                                    _gigShow = curating ? new GigShowEdit() : new GigShow();
                                    _gigShow.Editing = curating;
                                    _gigShow.Curating = curating;
                                    _gigShow.InitializeAw(
                                        aw,
                                        new Dictionary(
                                            "PartitionKey", "pg/gigs/" + ThemeYoshi.CurrentPageName,
                                            "RowKey", ThemeYoshi.CuratorId,
                                            "PageSelectTo", "#PageGigs",
                                            "PageCssTo", "#" + Master.PageMasterId,
                                            "SlideControls", slideControls,
                                            "HasSelect", false,
                                            "NoSlides", true
                                            )
                                        );
                                    Retitle();
                                }
                    )
                    ;
            else
                awx
                .LoadScript(gigLib,
                    delegate(Await aw)
                    {
                        if (_gigShow != null)
                            _gigShow.Destroy();
                        _gigShow = curating ? new GigShowEdit() : new GigShow();
                        _gigShow.Editing = curating;
                        _gigShow.Curating = curating;
                        _gigShow.InitializeAw(
                            aw,
                            new Dictionary(
                                "PartitionKey", "pg/gigs/" + ThemeYoshi.CurrentPageName,
                                "RowKey", ThemeYoshi.CuratorId,
                                "PageSelectTo", "#PageGigs",
                                "PageCssTo", "#" + Master.PageMasterId,
                                "SlideControls", slideControls,
                                "HasSelect", false,
                                "NoSlides", true
                                )
                            );
                        Retitle();
                    }
                )
                ;
            awx
                .AddDl(delegate(Await aw) { _gigShow.LoadAw(aw); })
                .Commit(awp);
        }
    }
}